#ifndef __VECTOR2_H__
#define __VECTOR2_H__

#include "Vector.h"

template <class Real>
class Vector2 
{
public:
	// construction
	Vector2<Real> ();
	Vector2<Real> (Real x, Real y);
	Vector2<Real> (Real coordinates[2]);
	Vector2<Real> (const Vector2<Real>& vec);

	// member access
	Real X() const;
	Real& X();
	Real Y() const;
	Real& Y();
	Real& operator[] (int i) const;

	// assignment 
	Vector2<Real>& operator= (const Vector2<Real>& vec);
	Vector2<Real>& operator= (const Vector<2,Real>& vec);
	bool operator== ( const Vector2<Real>& vec) const;
	bool operator!= ( const Vector2<Real>& vec) const;
	
	Vector2<Real>& operator + ( const Vector2<Real>& vec ) const;
	Vector2<Real>& operator - ( const Vector2<Real>& vec ) const;
	Vector2<Real>& operator * ( Real scalar ) const;
	Vector2<Real>& operator / ( Real scalar ) const;
	Vector2<Real>& operator - ( ) const;

	// arithmetic updates
	Vector2<Real>& operator+= ( const Vector2<Real>& vector )const;
    Vector2<Real>& operator-= ( const Vector2<Real>& vector )const;
    Vector2<Real>& operator*= ( const Vector2<Real>& vector )const;
    Vector2<Real>& operator/= ( Real fscalar );

	Real length() const;
	Real squared_length() const;
	Real dot( const Vector2<Real>& vec ) const;
	Real unitize( Real tolerance = 1e-06 );
	 
	// returns (y,-x)
	Vector2<Real> perp() const;

	// returns (y,-x)/sqrt(x*x+y*y)
	Vector2<Real> unit_perp() const;

	// returns Cross((x,y,0),(V.x,V.y,0)) = x*V.y - y*V.x
	Real cross( const Vector2<Real>& vec ) const;
	Vector2<Real> unit_cross( const Vector2<Real>& vec ) const;

	// Graham-Schmidt orthonormalization. Take linearly independent vectors u
	// and V and compute an orthonormal set (unit lenght, mutually perpendicular).
	static void orthonormalize( Vector2<Real>& u, Vector2<Real>& v );

	// Input V must be initialize to a nonzero vector, output is {U,V}, an
	// orthonormal basis. A hint is provided about whether or not V is
	// already unit length.
	static void generate_orthonormal_basis( Vector2<Real>& u, Vector2<Real>& v,
		bool unitlen );

	// special vectors
	static const Vector2<Real> ZERO;
	static const Vector2<Real> UNIT_X;
	static const Vector2<Real> UNIT_Y;
private:
	Real x,y;
};

typedef Vector2<float> Vector2f;
typedef Vector2<double> Vector2d;

#endif
